/**
 * This is a test suite for testing an implementation of the MyMap
 * interface.  To test the implementation, it is tested against a
 * Java standard Map for equality.  
 */

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.TreeMap;

public class MyMapTests
{
	
	// TODO: Add your own tests!
	
	public static void stressTest()
	{
		final int niter = 10000;
		
		// Initialize test and reference structures
		MyMap<Integer, String> test = new MyTreeMap<Integer, String>();
		Map<Integer, String> ref = new TreeMap<Integer, String>();
		
		// Try seeding the number generator to generate the "same" errors
		Random rand = new Random();
		
		for (int k = 0; k < niter; k++)
		{
			// Insert a random element
			if (rand.nextInt(100) < 60 || ref.keySet().size() == 0)
			{
				Integer key = new Integer(rand.nextInt());
				String val = rand.nextInt() + " blah";
				test.put(key, val);
				ref.put(key, val);
			}
			// Remove an existing element
			else
			{
				List<Integer> L = new ArrayList<Integer>(ref.keySet());
				Integer key = L.get(rand.nextInt(L.size()));
				test.remove(key);
				ref.remove(key);
			}
			
			// Check that the test map equals the reference map
			if (!checkForEquality(test, ref))
			{
				//System.out.println(test);
				//System.out.println(ref);
				throw new RuntimeException("Equality check failed");
			}
		}
		
		// Success!
		System.out.println("Stress test passed");
		
	}
	
	public static <K, V> boolean checkForEquality(MyMap<K, V> test, Map<K, V> ref)
	{
		// Check keys
		Set<K> testset = test.keySet();
		Set<K> refset = ref.keySet();
		if (!testset.equals(refset))
		{
			System.out.println("** KEY SETS NOT EQUAL **");
			System.out.println("test:" + testset);
			System.out.println("ref:" + refset);
			return false;
		}
		
		// Check values
		List<K> testkeys = new ArrayList<K>(testset);
		for (int k = 0; k < testkeys.size(); k++)
		{
			K testkey = testkeys.get(k);
			if (!test.get(testkey).equals(ref.get(testkey)))
			{
				System.out.println("** VALUES NOT EQUAL **");
				return false;
			}
		}
		
		// Done
		return true;
	}
	
	public static void main(String[] args)
	{
		// TODO: Add your own tests!
		stressTest();
	}
	
}
